package com.shhm.common.utils;

import com.shhm.common.entity.system.UserRole;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.security.Key;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author JackZ
 * @version 1.0
 * @description: 令牌相关工具类
 * @date 2025/7/22 下午2:48
 */
public class JwtUtil {
    private static final String SECRET="torunthissystemcallsecondhandhivemallbycreatercallakajackandcreatetimein2025710";
    private static final  Key SECRET_KEY = Keys.hmacShaKeyFor(Base64.getDecoder().decode(SECRET));
    // 过期时间（毫秒），当前设置半小时
    private static final long EXPIRATION=1800000;

    /**
     * 创建token
     * @param username 用户名
     * @param userId 用户id
     * @param roles 权限列表
     * @return token
     */
    public static String createToken(String username,String relName, long userId, List<UserRole> roles){
        ArrayList<String> rk = new ArrayList<>();
        roles.forEach(r->rk.add("ROLE_"+r.getRoleKey()));
        // 构建自定义claims
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);
        claims.put("realName", relName);
        claims.put("role", rk);

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 过期时间
                .signWith(SECRET_KEY)
                .compact();
    }

    /**
     * 解析JWT
     * @param token JWT令牌
     * @return Claims对象
     */
    public static Claims parseToken(String token) {
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY)
                .build()
                .parseClaimsJws(token)
                .getBody();

        return claims;
    }
    /**
     * 验证JWT是否有效
     * @param token JWT令牌
     * @return 是否有效
     */
    public static String validateToken(String token) {
        String valires;
        try {
            parseToken(token);
            valires= "pass";
        } catch (SignatureException e) {
            // 签名异常
//            System.err.println("无效的JWT签名: " + e.getMessage());
            valires= "无效的JWT签名";
        } catch (MalformedJwtException e) {
            // JWT格式错误
//            System.err.println("无效的JWT: " + e.getMessage());
            valires= "无效的令牌";
        } catch (ExpiredJwtException e) {
            // JWT过期
//            System.err.println("JWT已过期: " + e.getMessage());
            valires= "令牌已过期";
        } catch (UnsupportedJwtException e) {
            // 不支持的JWT
//            System.err.println("不支持的JWT: " + e.getMessage());
            valires="不支持的JWT";
        } catch (IllegalArgumentException e) {
            // 参数错误
//            System.err.println("JWT claims字符串为空: " + e.getMessage());
            valires= "JWT claims字符串为空";
        } catch (Exception e){
            valires = "JWT遇到未知的异常";
        }
        return valires;
    }

    /**
     * 处理请求体Authorization值为token字符串解析
     * @param authStr
     * @return token
     */
    public static String handleAuthorizationString(String authStr){
        if (authStr != null && authStr.startsWith("Bearer ")) {
            authStr = authStr.substring(7); // 去掉 "Bearer " 前缀
        }
        return authStr;
    }

    /**
     * 从JWT中解析用户角色
     *
     * @param token JWT令牌
     * @return 用户角色
     */
    public static List getRoleFromToken(String token) {
        Claims claims = parseToken(token);
        return claims.get("role", List.class);
    }

    /**
     * 从JWT中解析用户id
     * @param token JWT令牌
     * @return 用户id
     */
    public static Integer getUIDFromToken(String token) {
        Claims claims = parseToken(token);
        return claims.get("userId", Integer.class);
    }

    /**
     * 从Header中解析用户id
     * @param request Header
     * @return 用户id
     */
    public static Long getUIDFromAuth(HttpServletRequest request) {
        String token = handleAuthorizationString(request.getHeader("Authorization"));
        Claims claims = parseToken(token);
        return claims.get("userId", Long.class);
    }

    /**
     * 从JWT中解析用户id
     * @param token JWT令牌
     * @return 用户id
     */
    public static String getRealNameFromToken(String token) {
        Claims claims = parseToken(token);
        return claims.get("realName", String.class);
    }

    /**
     * 判断令牌是否过期
     * @param token
     * @return boolean
     */
    public static boolean isExpired(String token) {
        Claims claims = parseToken(token);
        return claims.getExpiration().before(new Date());
    }

    /**
     * 获取令牌生存时间
     * @param token
     * @return boolean
     */
    public static Long getExpired(String token) {
        Claims claims = parseToken(token);
        Date expiration = claims.getExpiration();
        return (expiration.getTime() - System.currentTimeMillis()) / 1000;
    }

    /**
     * 获取username
     * @param token
     * @return String   */
    public static String getUsernameFromToken(String token) {
        Claims claims = parseToken(token);
        return claims.getSubject();
    }

    /**
     * 构建Authentication令牌
     * @param token
     * @return
     */
    public static Authentication buildAuthentication(String token) {
        Claims claims = parseToken(token);

        // 从JWT提取角色信息
        List<String> roles = claims.get("role", List.class);
        List<SimpleGrantedAuthority> authorities = roles.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());

        // 构建认证对象
        return new UsernamePasswordAuthenticationToken(
                claims.getSubject(), // 用户名
                null,               // 凭证置空
                authorities
        );
    }
}
